home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Mac / Lib / EasyDialogs.py < prev    next >
Encoding:
Python Source  |  2000-06-23  |  9.2 KB  |  343 lines

  1. """Easy to use dialogs.
  2.  
  3. Message(msg) -- display a message and an OK button.
  4. AskString(prompt, default) -- ask for a string, display OK and Cancel buttons.
  5. AskPassword(prompt, default) -- like AskString(), but shows text as bullets.
  6. AskYesNoCancel(question, default) -- display a question and Yes, No and Cancel buttons.
  7. bar = Progress(label, maxvalue) -- Display a progress bar
  8. bar.set(value) -- Set value
  9. bar.inc( *amount ) -- increment value by amount (default=1)
  10. bar.label( *newlabel ) -- get or set text label. 
  11.  
  12. More documentation in each function.
  13. This module uses DLOG resources 256, 257 and 258.
  14. Based upon STDWIN dialogs with the same names and functions.
  15. """
  16.  
  17. from Dlg import GetNewDialog, SetDialogItemText, GetDialogItemText, ModalDialog
  18. import Qd
  19. import QuickDraw
  20. import Dialogs
  21. import Windows
  22. import Dlg,Win,Evt,Events # sdm7g
  23. import MacOS
  24. import string
  25.  
  26. def cr2lf(text):
  27.     if '\r' in text:
  28.         text = string.join(string.split(text, '\r'), '\n')
  29.     return text
  30.  
  31. def lf2cr(text):
  32.     if '\n' in text:
  33.         text = string.join(string.split(text, '\n'), '\r')
  34.     if len(text) > 253:
  35.         text = text[:253] + '\311'
  36.     return text
  37.  
  38. def Message(msg, id=256, ok=None):
  39.     """Display a MESSAGE string.
  40.     
  41.     Return when the user clicks the OK button or presses Return.
  42.     
  43.     The MESSAGE string can be at most 255 characters long.
  44.     """
  45.     
  46.     d = GetNewDialog(id, -1)
  47.     if not d:
  48.         print "Can't get DLOG resource with id =", id
  49.         return
  50.     tp, h, rect = d.GetDialogItem(2)
  51.     SetDialogItemText(h, lf2cr(msg))
  52.     if ok != None:
  53.         tp, h, rect = d.GetDialogItem(1)
  54.         h.as_Control().SetControlTitle(ok)
  55.     d.SetDialogDefaultItem(1)
  56.     while 1:
  57.         n = ModalDialog(None)
  58.         if n == 1:
  59.             return
  60.  
  61.  
  62. def AskString(prompt, default = "", id=257, ok=None, cancel=None):
  63.     """Display a PROMPT string and a text entry field with a DEFAULT string.
  64.     
  65.     Return the contents of the text entry field when the user clicks the
  66.     OK button or presses Return.
  67.     Return None when the user clicks the Cancel button.
  68.     
  69.     If omitted, DEFAULT is empty.
  70.     
  71.     The PROMPT and DEFAULT strings, as well as the return value,
  72.     can be at most 255 characters long.
  73.     """
  74.     
  75.     id = 257
  76.     d = GetNewDialog(id, -1)
  77.     if not d:
  78.         print "Can't get DLOG resource with id =", id
  79.         return
  80.     tp, h, rect = d.GetDialogItem(3)
  81.     SetDialogItemText(h, lf2cr(prompt))
  82.     tp, h, rect = d.GetDialogItem(4)
  83.     SetDialogItemText(h, lf2cr(default))
  84.     d.SelectDialogItemText(4, 0, 999)
  85. #    d.SetDialogItem(4, 0, 255)
  86.     if ok != None:
  87.         tp, h, rect = d.GetDialogItem(1)
  88.         h.as_Control().SetControlTitle(ok)
  89.     if cancel != None:
  90.         tp, h, rect = d.GetDialogItem(2)
  91.         h.as_Control().SetControlTitle(cancel)
  92.     d.SetDialogDefaultItem(1)
  93.     d.SetDialogCancelItem(2)
  94.     while 1:
  95.         n = ModalDialog(None)
  96.         if n == 1:
  97.             tp, h, rect = d.GetDialogItem(4)
  98.             return cr2lf(GetDialogItemText(h))
  99.         if n == 2: return None
  100.  
  101. def AskPassword(prompt,     default='', id=257):    
  102.     """Display a PROMPT string and a text entry field with a DEFAULT string.
  103.     The string is displayed as bullets only.
  104.     
  105.     Return the contents of the text entry field when the user clicks the
  106.     OK button or presses Return.
  107.     Return None when the user clicks the Cancel button.
  108.     
  109.     If omitted, DEFAULT is empty.
  110.     
  111.     The PROMPT and DEFAULT strings, as well as the return value,
  112.     can be at most 255 characters long.
  113.     """
  114.     d = GetNewDialog(id, -1)
  115.     if not d:
  116.         print "Can't get DLOG resource with id =", id
  117.         return
  118.     tp, h, rect = d.GetDialogItem(3)    # STATIC TEXT ITEM <= prompt 
  119.     SetDialogItemText(h, lf2cr(prompt))    
  120.     tp, h, rect = d.GetDialogItem(4)    # EDIT TEXT ITEM 
  121.     bullets = '\245'*len(default)
  122.     SetDialogItemText(h, bullets )
  123.     d.SelectDialogItemText(4, 999, 999)
  124.     d.SetDialogDefaultItem(Dialogs.ok)
  125.     d.SetDialogCancelItem(Dialogs.cancel)
  126.     string = default
  127.     oldschedparams = MacOS.SchedParams(0,0)
  128.     while 1:
  129.         ready,ev = Evt.WaitNextEvent(Events.everyEvent, 6)
  130.         if not ready: continue
  131.         what,msg,when,where,mod = ev
  132.         if what == 0 : Dlg.DialogSelect(ev)    # for blinking caret
  133.         elif Dlg.IsDialogEvent(ev):
  134.             if what in (Events.keyDown, Events.autoKey):
  135.                 charcode = msg & Events.charCodeMask
  136.                 if ( mod & Events.cmdKey ):
  137.                     MacOS.SysBeep()
  138.                     continue    # don't do cut & paste commands
  139.                 else:    
  140.                     if charcode == Events.kReturnCharCode:
  141.                         break
  142.                     elif charcode == Events.kEscapeCharCode:
  143.                         string = None
  144.                         break
  145.                     elif charcode in (Events.kLeftArrowCharCode,
  146.                                 Events.kBackspaceCharCode):
  147.                         string = string[:-1]
  148.                     else:
  149.                         string = string + chr(charcode)
  150.                         msg =  0245   # Octal code for bullet
  151.                         ev = (what,msg,when,where,mod)
  152.             rs, win, item = Dlg.DialogSelect(ev)
  153.             if item == Dialogs.ok :
  154.                 break    
  155.             elif item == Dialogs.cancel :
  156.                 string = None
  157.                 break
  158.         elif what == Events.mouseDown:
  159.             part, win = Win.FindWindow(where)
  160.             if part == Windows.inDrag and win:
  161.                 win.DragWindow(where, screenbounds)
  162.             elif part == Windows.inMenuBar:
  163.                 MacOS.HandleEvent(ev)
  164.             else:
  165.                 MacOS.SysBeep()        # Cannot handle selections, unfortunately
  166.             
  167.         elif what == Events.updateEvt: MacOS.HandleEvent(ev)
  168.     apply(MacOS.SchedParams, oldschedparams)
  169.     return string
  170.  
  171. def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=258):
  172.     """Display a QUESTION string which can be answered with Yes or No.
  173.     
  174.     Return 1 when the user clicks the Yes button.
  175.     Return 0 when the user clicks the No button.
  176.     Return -1 when the user clicks the Cancel button.
  177.     
  178.     When the user presses Return, the DEFAULT value is returned.
  179.     If omitted, this is 0 (No).
  180.     
  181.     The QUESTION strign ca be at most 255 characters.
  182.     """
  183.     
  184.     d = GetNewDialog(id, -1)
  185.     if not d:
  186.         print "Can't get DLOG resource with id =", id
  187.         return
  188.     # Button assignments:
  189.     # 1 = default (invisible)
  190.     # 2 = Yes
  191.     # 3 = No
  192.     # 4 = Cancel
  193.     # The question string is item 5
  194.     tp, h, rect = d.GetDialogItem(5)
  195.     SetDialogItemText(h, lf2cr(question))
  196.     if yes != None:
  197.         tp, h, rect = d.GetDialogItem(2)
  198.         h.as_Control().SetControlTitle(yes)
  199.     if no != None:
  200.         tp, h, rect = d.GetDialogItem(3)
  201.         h.as_Control().SetControlTitle(no)
  202.     if cancel != None:
  203.         if cancel == '':
  204.             d.HideDialogItem(4)
  205.         else:
  206.             tp, h, rect = d.GetDialogItem(4)
  207.             h.as_Control().SetControlTitle(cancel)
  208.     d.SetDialogCancelItem(4)
  209.     if default == 1:
  210.         d.SetDialogDefaultItem(2)
  211.     elif default == 0:
  212.         d.SetDialogDefaultItem(3)
  213.     elif default == -1:
  214.         d.SetDialogDefaultItem(4)
  215.     while 1:
  216.         n = ModalDialog(None)
  217.         if n == 1: return default
  218.         if n == 2: return 1
  219.         if n == 3: return 0
  220.         if n == 4: return -1
  221.  
  222.  
  223.         
  224.  
  225. screenbounds = Qd.qd.screenBits.bounds
  226. screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
  227.     screenbounds[2]-4, screenbounds[3]-4
  228.  
  229.                 
  230. class ProgressBar:
  231.     def __init__(self, title="Working...", maxval=100, label="", id=259):
  232.         self.maxval = maxval
  233.         self.curval = -1
  234.         self.d = GetNewDialog(id, -1)
  235.         self.title(title)
  236.         self.label(label)
  237.         self._update(0)
  238.  
  239.     def __del__( self ):
  240.         self.d.BringToFront()
  241.         self.d.HideWindow()
  242.         del self.d
  243.         
  244.     def title(self, newstr=""):
  245.         """title(text) - Set title of progress window"""
  246.         self.d.BringToFront()
  247.         w = self.d.GetDialogWindow()
  248.         w.SetWTitle(newstr)
  249.         
  250.     def label( self, *newstr ):
  251.         """label(text) - Set text in progress box"""
  252.         self.d.BringToFront()
  253.         if newstr:
  254.             self._label = lf2cr(newstr[0])
  255.         tp, text_h, rect = self.d.GetDialogItem(2)
  256.         SetDialogItemText(text_h, self._label)        
  257.  
  258.                 
  259.     def _update(self, value):
  260.         self.d.BringToFront()
  261.         tp, h, bar_rect = self.d.GetDialogItem(3)
  262.         Qd.SetPort(self.d)
  263.         
  264.         Qd.FrameRect(bar_rect)    # Draw outline
  265.         
  266.         inner_rect = Qd.InsetRect(bar_rect, 1, 1)
  267.         l, t, r, b = inner_rect
  268.  
  269.         Qd.ForeColor(QuickDraw.blackColor)
  270.         Qd.BackColor(QuickDraw.blackColor)
  271.         Qd.PaintRect((l, t, int(l + (r-l)*value/self.maxval), b))    # Draw bar
  272.  
  273.         Qd.ForeColor(QuickDraw.whiteColor)
  274.         Qd.BackColor(QuickDraw.whiteColor)
  275.         Qd.PaintRect((int(l + (r-l)*value/self.maxval), t, r, b))    # Clear rest
  276.                 
  277.         # Restore settings
  278.         Qd.ForeColor(QuickDraw.blackColor)
  279.         Qd.BackColor(QuickDraw.whiteColor)
  280.         
  281.         # Test for cancel button
  282.         
  283.         ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1  )
  284.         if ready : 
  285.             what,msg,when,where,mod = ev
  286.             part = Win.FindWindow(where)[0]
  287.             if Dlg.IsDialogEvent(ev):
  288.                 ds = Dlg.DialogSelect(ev)
  289.                 if ds[0] and ds[1] == self.d and ds[-1] == 1:
  290.                     raise KeyboardInterrupt, ev
  291.             else:
  292.                 if part == 4:    # inDrag 
  293.                     self.d.DragWindow(where, screenbounds)
  294.                 else:
  295.                     MacOS.HandleEvent(ev) 
  296.             
  297.             
  298.     def set(self, value):
  299.         """set(value) - Set progress bar position"""
  300.         if value < 0: value = 0
  301.         if value > self.maxval: value = self.maxval
  302.         self.curval = value
  303.         self._update(value)
  304.  
  305.     def inc(self, n=1):
  306.         """inc(amt) - Increment progress bar position"""
  307.         self.set(self.curval + n)
  308.  
  309. def test():
  310.     import time
  311.  
  312.     Message("Testing EasyDialogs.")
  313.     ok = AskYesNoCancel("Do you want to proceed?")
  314.     ok = AskYesNoCancel("Do you want to identify?", yes="Indentify", no="Don't identify")
  315.     if ok > 0:
  316.         s = AskString("Enter your first name", "Joe")
  317.         Message("Thank you,\n%s" % `s`)
  318.     text = ( "Working Hard...", "Hardly Working..." , 
  319.             "So far, so good!", "Keep on truckin'" )
  320.     bar = ProgressBar("Progress, progress...", 100)
  321.     try:
  322.         appsw = MacOS.SchedParams(1, 0)
  323.         for i in range(100):
  324.             bar.set(i)
  325.             time.sleep(0.1)
  326.             if i % 10 == 0:
  327.                 bar.label(text[(i/10) % 4])
  328.         bar.label("Done.")
  329.         time.sleep(0.3)     # give'em a chance to see the done.
  330.     finally:
  331.         del bar
  332.         apply(MacOS.SchedParams, appsw)
  333.  
  334.  
  335.     
  336.     
  337. if __name__ == '__main__':
  338.     try:
  339.         test()
  340.     except KeyboardInterrupt:
  341.         Message("Operation Canceled.")
  342.  
  343.